package net.xiduth.algorithms;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Date;

/**
 * @author Bart
 * 
 * @since 18-6-2013
 */
public class Encryption {

	/** Represents this encryptions String to be encrypted */
	private String encryption;

	/** Represents the date of this encryption */
	private Date date;

	/** Represents the encryption type algorithm used to encrypt the string */
	private String algorithm;

	/**
	 * Constructs a new Encryption with a date and algorithm type.
	 * 
	 * @param encryption
	 *            - The String to encrypt
	 * @param algorithm
	 *            - The encryption type used to encrypt the string
	 * @param date
	 *            - The date of this encryption
	 */
	public Encryption(String encryption, String algorithm, Date date) {
		this.encryption = encryption;
		this.date = date;
		this.algorithm = algorithm;
	}

	/**
	 * Encrypts the buffer using MD5 type encryption. This will generate an
	 * encryption seed using {@link MessageDigest} and will update the
	 * encryption seed and the store it in the digest using a byte array
	 * 
	 * @param buffer
	 *            - the buffer to be encrypted
	 * @return - the digest seed from the encryption
	 */
	public static final byte[] MD5Encryption(byte[] buffer) {
		try {
			MessageDigest MD5 = MessageDigest.getInstance("MD5");
			MD5.update(buffer);
			byte[] digest = MD5.digest();
			MD5.reset();
			return digest;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * Encrypts a string using the algorithm SHA-1. The string is very unlikley
	 * to be decrypted. The SHA-1 encryption will digest a SHA-1 String and
	 * receive it's bytes using {@link MessageDigest}.
	 * 
	 * @param string
	 *            - the string to encrypt
	 * @return - an encrypted version of the specified string using SHA-1
	 */
	public static Encryption SHA1Encryption(String string) {
		byte[] encryptionType = digest(string, "SHA-1");
		StringBuffer s = new StringBuffer(encryptionType.length * 2);
		for (int i = 0; i < encryptionType.length;) {
			int nameIndex = encryptionType[i] & 0xff;
			if (nameIndex < 16) {
				s.append('0');
			}
			s.append(Integer.toHexString(nameIndex));
			return new Encryption(s.toString(), "SHA-1", Calendar.getInstance()
					.getTime());
		}
		return null;
	}

	/**
	 * Digests a string using an algorithm in MessageDigest
	 * 
	 * @param message
	 *            - the message to digest using an algorithm
	 * @param algorithm
	 *            - the algorithm used to digest this string
	 * @return - a digested version of the specified message
	 */
	public static byte[] digest(String message, String algorithm) {
		MessageDigest string = null;
		try {
			string = MessageDigest.getInstance(algorithm);
			string.reset();
			string.update(message.getBytes());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return string.digest();
	}

	/**
	 * Returns this encrypted string
	 * 
	 * @return - This encrypted string
	 */
	public String getEncryption() {
		return encryption;
	}

	/**
	 * Returns the date of this encryption
	 * 
	 * @return - This encryptions date
	 */
	public Date getDate() {
		return date;
	}

	/**
	 * Returns the algorithm used to encrypt the string
	 * 
	 * @return - The algorithm used to encrypt the string
	 */
	public String getAlgorithm() {
		return algorithm;
	}

}
